﻿package {
	import flash.display.MovieClip;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.geom.Rectangle;
	import flash.geom.Point;
	import flash.events.Event;
	import fl.transitions.Tween;
	import fl.transitions.TweenEvent;
	import fl.transitions.easing.Bounce;
	import fl.transitions.easing.None;
	
	public class Piece extends MovieClip {
		/*
		This class will be the actual tile piece, containing properties such as its desinated x,y position.
		It also contain methods such as animating to its desinated position, as well as picking a random spot on stage at frist.
		
		Once called, this tile will tween to its desinated position (actualX, actualY).
		As each tween (x, y, alpha) finishes its animation, it will check to see if all other tweens are completed as well.
		If all tweening is done, that means this tile has completed its duty, and can add 1 to the completed count "completedTween" back to the document class.
		*/
		
		// variable to store the actual x,y locations of this particular tile piece.
		private var actualX:Number;
		private var actualY:Number;
		
		// number of seconds (maximum) the tween should last.
		private var aniDuration:Number = 2;
		
		// Tween references, for each dimension movement as well as the alpha fade.
		private var tileTweenX:Tween;
		private var tileTweenY:Tween;
		private var tileTweenA:Tween;
		
		public function Piece (w:Number, h:Number, r:Number, c:Number, img:BitmapImage) {
			/*
			w : the width of the tile
			h : the height of the tile
			r : the row number that the tile represents on the grid
			c : the column number that the tile represents on the grid
			img : the BitmapData containing the actual image, as we will copy a section of it later
			imgHolder : a reference to the holder movie clip, so that we can calculate the offset position when placing randomly on stage (randomPosition())			
			
			Constructor method: this will initialize the Piece class by:
			- setting the initial alpha to 0.1
			- copying a section from the actual image (the pixel data), by precalculated x, y, width & heights
			- using that copied seection and display it as its own Bitmap information, thus creating a "tile piece"
			*/
			this.alpha = 0.1;
			var bData:BitmapData = new BitmapData (w, h);
			// The x,y of the rectangle is determinded by the position of the "grid", calculated from the document class
			var rect:Rectangle = new Rectangle (r * w, c * h, w, h);
			var pt:Point = new Point (0, 0);
			bData.copyPixels (img, rect, pt);
			var bitmap:Bitmap = new Bitmap (bData);
			
			actualX = r * w;
			actualY = c * h;
			// once everything has been set up, attach the bitmap to itself as a movie clip.
			addChild (bitmap);
			
			// position itself to a random spot once added on stage
			this.addEventListener (Event.ADDED_TO_STAGE, randomPosition);
		}
		
		
		public function randomPosition (evt:Event) : void {
			/*
			This method will be called once the tile piece instance is added to the stage. We will need to calculate a random x,y position for this tile to be at as soon as this tile is added on stage.
			By referencing "root as Preloader", we can reference back to the document class and point to imgHolder, the movie clip on the stage, so we will know the x,y offset when calculating the position. 
			This will allow the tile not to go off screen.			
			*/
			var rootPreloader:Preloader = root as Preloader;
			var holder:MovieClip = rootPreloader.imgHolder;
			var randomX:Number = (Math.random() * stage.stageWidth) - holder.x;
			var randomY:Number = (Math.random() * stage.stageHeight) - holder.y;
			this.x = randomX;
			this.y = randomY;
		}
		
		public function moveToPosition () : void {
			/*
			This method will be called as soon as the movie's loaded percentage is greater than the tile's associated number.
			The 3 tweens x, y, alpha will immeidately tween to position.
			An event will be triggered once each tween is completed.
			*/
			tileTweenX = new Tween (this, "x", Bounce.easeOut, this.x, actualX, Math.random() * aniDuration, true);
			tileTweenY = new Tween (this, "y", Bounce.easeOut, this.y, actualY, Math.random() * aniDuration, true);
			tileTweenA = new Tween (this, "alpha", None.easeIn, this.alpha, 1, Math.random() * aniDuration, true);
			tileTweenX.start();
			tileTweenY.start();
			tileTweenA.start();
			
			tileTweenX.addEventListener (TweenEvent.MOTION_FINISH, onTweenEnd);
			tileTweenY.addEventListener (TweenEvent.MOTION_FINISH, onTweenEnd);
			tileTweenA.addEventListener (TweenEvent.MOTION_FINISH, onTweenEnd);
		}
		
		private function onTweenEnd (evt:TweenEvent) : void {
			// When all 3 tweens are done, remove all event listeners and add 1 to the completed tween count in the document class.
			if (tileTweenX.position == tileTweenX.finish && tileTweenY.position == tileTweenY.finish && tileTweenA.position == tileTweenA.finish) {
				tileTweenX.removeEventListener (TweenEvent.MOTION_FINISH, onTweenEnd);
				tileTweenY.removeEventListener (TweenEvent.MOTION_FINISH, onTweenEnd);
				tileTweenA.removeEventListener (TweenEvent.MOTION_FINISH, onTweenEnd);
				var rootPreloader:Preloader = root as Preloader;
				rootPreloader.completedTween++;
			}
		}
	}	
}